package ie.timalb.chess.main.core;

import ie.timalb.chess.main.core.exceptions.NoPieceInSrcSquareException;
import ie.timalb.chess.main.core.exceptions.ImpossibleToTraceARouteException;
import ie.timalb.chess.main.core.exceptions.SquareOutOfRangeException;
import ie.timalb.chess.main.core.movement.Location;
import ie.timalb.chess.main.core.movement.Movement;
import ie.timalb.chess.main.core.movement.MovementDescriptor;
import ie.timalb.chess.main.core.pieces.Piece;
import ie.timalb.chess.main.core.squares.Square;
import ie.timalb.chess.main.core.squares.SquareManager;
import ie.timalb.chess.main.core.squares.SquareWithPiece;
import ie.timalb.chess.main.core.temp.SquareIterator;
import ie.timalb.chess.main.core.temp.Squares;


public class Board implements SquareManager {
	Squares squares;	
	
	public enum MAXCOORDS
	{
		XCORD, YCORD;
		
		private int value = 8;
		
		public int getValue ()
		{
			return value;
		}
	}
	
	public enum MINCOORDS
	{
		XCORD, YCORD;
		
		private int value = 1;
		
		public int getValue ()
		{
			return value;
		}
	}
	
	public Board()
	{
		squares = new Squares(this);
		int minCoordX = MINCOORDS.XCORD.getValue();
		int maxCoordX = MAXCOORDS.XCORD.getValue();
		int minCoordY = MINCOORDS.YCORD.getValue();
		int maxCoordY = MAXCOORDS.YCORD.getValue();
		
		for (int currentCoordX = minCoordX; currentCoordX <= maxCoordX; currentCoordX++)
		{
			for (int currentCoordY = minCoordY; currentCoordY <= maxCoordY; currentCoordY++)
			{
				try 
				{
					getSquares().createEmptySquare(currentCoordX, currentCoordY);
				} catch (SquareOutOfRangeException e) {
					throw new RuntimeException (e);					
				}				
			}
		}
	}
	
	public void addPiece(Piece piece, Location location) throws SquareOutOfRangeException
	{
		getSquares().addPiece(piece, location);		
	}

	public boolean contains(Square destLocation) {
		return getSquares().contains(destLocation);
	}
		
	private Squares getSquares ()
	{
		return squares;
	}

	public Square getSquare(int x, int y) throws SquareOutOfRangeException {
		return getSquare (new Location (x,y));
	}
	
	public Square getSquare(String sourceSquare) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public Square getSquare (Location location) throws SquareOutOfRangeException
	{		
		return getSquares().getSquare(location);		
	}

	public int getSquareCount() {
		return getSquares().getSquareCount();
	}

	public SquareIterator getSquareIterator(MovementDescriptor descriptor, Location startLocation, Location endLocation) {
		return getSquares().getSquareIterator();
		
	}

	public Square getPreviousSquare(Square sourceSquare, MovementDescriptor direction) throws SquareOutOfRangeException {
		Location previousLocation = sourceSquare.getPreviousLocation(direction);
		return getSquare(previousLocation);
	}

	public Square getNextSquare(Square sourceSquare, MovementDescriptor direction) throws SquareOutOfRangeException {
		Location nextLocation = sourceSquare.getNextSquare(direction);
		return getSquare(nextLocation);
	}

	public Movement createMovement(Location srcLocation, Location dtnyLocation) 
	throws SquareOutOfRangeException, NoPieceInSrcSquareException, ImpossibleToTraceARouteException {
		return createMovement(getSquare(srcLocation), getSquare(dtnyLocation));			
	}
	
	public Movement createMovement(Square srcSquare, Square dtnySquare) 
	throws NoPieceInSrcSquareException, ImpossibleToTraceARouteException, SquareOutOfRangeException {
		if (srcSquare.isOccupied())
		{
			return createMovement ((SquareWithPiece) srcSquare, dtnySquare);	
		}else
		{
			throw new NoPieceInSrcSquareException ();
		}
		
	}	

	public Movement createMovement(SquareWithPiece square, Square square2) 
	throws ImpossibleToTraceARouteException, SquareOutOfRangeException {
		return new Movement (square, square2);
	}
		
}
